1
00:00:02,100 --> 00:00:05,740
现在让我们转换这个 Users 组件

2
00:00:05,740 --> 00:00:08,420
到基于类的组件。

3
00:00:08,420 --> 00:00:12,660
为此，我们应该再次从 React 中导入一些东西。

4
00:00:12,660 --> 00:00:14,850
让我重组这些导入。

5
00:00:14,850 --> 00:00:19,310
我们应该从react导入组件

6
00:00:20,380 --> 00:00:23,600
因为我们现在构建了用户组件

7
00:00:23,600 --> 00:00:28,320
通过创建一个名为 Users 的类来扩展 Component。

8
00:00:28,320 --> 00:00:30,630
这就是我在上一讲中解释的

9
00:00:30,630 --> 00:00:34,713
这就是构建基于类的组件的方式。

10
00:00:35,890 --> 00:00:38,730
现在我们可以在其中添加渲染方法

11
00:00:38,730 --> 00:00:42,620
在该 render 方法中，我们返回 jsx 代码

12
00:00:42,620 --> 00:00:44,260
应该渲染它。

13
00:00:44,260 --> 00:00:46,410
所以，我将复制此退货声明

14
00:00:46,410 --> 00:00:48,253
并将其带入我的渲染方法中。

15
00:00:49,670 --> 00:00:54,010
现在我们知道我们可以通过这些 props 来访问 props

16
00:00:54,010 --> 00:00:56,330
但在这里我不使用道具

17
00:00:56,330 --> 00:00:58,960
相反，我依赖于状态

18
00:00:58,960 --> 00:01:01,480
我指着一个函数

19
00:01:01,480 --> 00:01:04,030
单击按钮时应执行该操作。

20
00:01:05,290 --> 00:01:08,670
现在让我们开始添加该函数。

21
00:01:08,670 --> 00:01:10,590
在基于类的组件中，

22
00:01:10,590 --> 00:01:15,030
您现在不要在渲染方法中添加函数

23
00:01:15,030 --> 00:01:17,340
虽然这在技术上是可能的

24
00:01:17,340 --> 00:01:19,960
但它的行为不正确。

25
00:01:19,960 --> 00:01:22,300
但相反，因为这是一堂课，

26
00:01:22,300 --> 00:01:24,930
将功能组合在一起

27
00:01:24,930 --> 00:01:27,510
将其全部分组到该类中。

28
00:01:27,510 --> 00:01:30,330
所以你只需添加一个方法

29
00:01:30,330 --> 00:01:33,483
像这样命名为toggleUsersHandler。

30
00:01:34,500 --> 00:01:36,520
还有替代方法

31
00:01:36,520 --> 00:01:38,790
在类中编写方法

32
00:01:38,790 --> 00:01:41,680
但这是最默认和标准的方式

33
00:01:41,680 --> 00:01:43,213
定义一个方法。

34
00:01:45,330 --> 00:01:48,600
现在我们有了方法，但没有状态。

35
00:01:48,600 --> 00:01:52,860
管理状态的工作方式完全不同

36
00:01:52,860 --> 00:01:56,230
过去使用基于类的组件。

37
00:01:56,230 --> 00:02:00,200
随着react16.8引入了hooks

38
00:02:00,200 --> 00:02:02,500
我们可以使用 UseState 钩子

39
00:02:02,500 --> 00:02:05,540
管理状态和功能组件。

40
00:02:05,540 --> 00:02:08,453
那么管理状态就非常简单了。

41
00:02:10,030 --> 00:02:13,520
16.8 之前的基于类的组件

42
00:02:13,520 --> 00:02:17,100
是唯一可以管理状态的组件。

43
00:02:17,100 --> 00:02:20,120
所以你总是必须编写基于类的组件

44
00:02:20,120 --> 00:02:22,280
当你需要状态时。

45
00:02:22,280 --> 00:02:26,710
在那里你基本上需要做两件事，

46
00:02:26,710 --> 00:02:29,520
初始化并定义你的状态，

47
00:02:29,520 --> 00:02:33,650
就像我们第一次调用 UseState 时所做的那样

48
00:02:33,650 --> 00:02:35,950
然后在需要时更新，

49
00:02:35,950 --> 00:02:39,810
就像我们在toggleUsersHandler 中所做的那样。

50
00:02:39,810 --> 00:02:42,870
现在定义基于状态和类的组件，

51
00:02:42,870 --> 00:02:45,180
你会使用构造函数。

52
00:02:45,180 --> 00:02:48,200
自动调用构造函数

53
00:02:48,200 --> 00:02:51,090
每当这个子句被实例化时

54
00:02:51,090 --> 00:02:54,070
当react遇到时会发生这种情况，

55
00:02:54,070 --> 00:02:57,023
您的类被用作组件。

56
00:02:58,030 --> 00:03:01,600
然后在构造函数中，就可以做初始化工作了

57
00:03:01,600 --> 00:03:03,610
就像初始化状态一样。

58
00:03:03,610 --> 00:03:08,280
这可以通过访问 this.state 来完成

59
00:03:08,280 --> 00:03:10,770
并将其设置为等于一个对象。

60
00:03:10,770 --> 00:03:13,640
现在这非常关键。

61
00:03:13,640 --> 00:03:18,640
对于基于类的组件，您的状态始终很重要，

62
00:03:20,150 --> 00:03:23,240
始终是一个对象。

63
00:03:23,240 --> 00:03:27,410
使用功能组件，您的状态可以是任何东西。

64
00:03:27,410 --> 00:03:31,210
它可以只是一个布尔值、一个字符串、一个数字

65
00:03:31,210 --> 00:03:34,210
但它也可以是一个对象，但它很灵活

66
00:03:34,210 --> 00:03:35,653
它可以是任何东西。

67
00:03:36,630 --> 00:03:39,490
对于基于类的组件，情况并非如此。

68
00:03:39,490 --> 00:03:42,120
在这里你的状态始终是一个对象

69
00:03:43,440 --> 00:03:45,970
因为对于基于类的组件，

70
00:03:45,970 --> 00:03:50,440
你总是将所有州的许可证和部件分组

71
00:03:50,440 --> 00:03:54,510
您可能需要将一个组件转换为一个状态对象。

72
00:03:54,510 --> 00:03:56,520
具有功能组件

73
00:03:56,520 --> 00:03:59,520
相反，如果你有多个状态块，

74
00:03:59,520 --> 00:04:02,403
您可以使用多个 UseState 调用。

75
00:04:03,450 --> 00:04:06,770
您也可以只创建一个状态对象

76
00:04:06,770 --> 00:04:08,470
并将其组合在一起

77
00:04:08,470 --> 00:04:12,040
但这对于功能组件来说是可选的。

78
00:04:12,040 --> 00:04:15,893
我确实在州立课程部分谈到了这一点。

79
00:04:16,920 --> 00:04:19,870
对于基于类的组件，这不是可选的

80
00:04:19,870 --> 00:04:23,050
在那里你必须将所有状态分组

81
00:04:23,050 --> 00:04:25,710
它将一个组件组成一个对象。

82
00:04:25,710 --> 00:04:30,053
无论这些状态件是否密切相关。

83
00:04:31,040 --> 00:04:34,550
所以这里我们会有 showUsers 状态

84
00:04:34,550 --> 00:04:37,640
假设最初将其设置为 true 。

85
00:04:37,640 --> 00:04:39,403
如果我们有更多状态

86
00:04:40,450 --> 00:04:43,493
那么我们只需将其添加为额外属性即可。

87
00:04:44,420 --> 00:04:46,690
你当然也可以有nestedState，

88
00:04:46,690 --> 00:04:48,500
你可以有一个nestedObject。

89
00:04:48,500 --> 00:04:53,010
你可以拥有一个一切正常的擦除状态

90
00:04:53,010 --> 00:04:56,383
但你有一个状态对象将它们组合在一起。

91
00:04:58,210 --> 00:05:00,430
那么如果你想改变你的状态

92
00:05:00,430 --> 00:05:02,780
就像在toggleUsersHandler中一样，

93
00:05:02,780 --> 00:05:06,550
你不能通过访问这个状态来做到这一点

94
00:05:06,550 --> 00:05:11,113
像这样改变它，这不是你应该做的。

95
00:05:12,580 --> 00:05:17,580
相反，你调用一个特殊的方法，setState，this.setState，

96
00:05:20,460 --> 00:05:22,580
以及这个类上的这个方法

97
00:05:22,580 --> 00:05:25,800
当然也是组件类提供的

98
00:05:25,800 --> 00:05:27,363
我们继承自。

99
00:05:28,720 --> 00:05:33,720
此 setState 也始终采用一个对象。

100
00:05:34,750 --> 00:05:39,750
这个对象现在包含您想要设置的新状态，

101
00:05:39,820 --> 00:05:44,240
但非常重要，它不会覆盖旧状态

102
00:05:44,240 --> 00:05:47,240
而是在幕后做出反应

103
00:05:47,240 --> 00:05:50,130
合并您在此处传递的对象

104
00:05:50,130 --> 00:05:51,733
与您现有的状态。

105
00:05:52,760 --> 00:05:57,120
所以如果我这里有另一个状态，我在这里不需要

106
00:05:57,120 --> 00:06:02,120
如果我有这个，然后我会将 showUsers 设置为 false，

107
00:06:02,420 --> 00:06:04,770
showUsers 将被设置为 false

108
00:06:04,770 --> 00:06:06,920
但旧状态将受到限制。

109
00:06:06,920 --> 00:06:08,680
另一个州将受到限制

110
00:06:08,680 --> 00:06:12,800
因为 React 将此更新与现有状态合并

111
00:06:12,800 --> 00:06:15,420
它不会覆盖状态。

112
00:06:15,420 --> 00:06:18,190
这与 useState 不同，

113
00:06:18,190 --> 00:06:21,080
当你调用状态更新函数时

114
00:06:21,080 --> 00:06:24,070
你总是覆盖旧状态

115
00:06:24,070 --> 00:06:27,343
无论你传递给更新函数，

116
00:06:28,250 --> 00:06:30,210
除非它是一个函数，在这种情况下

117
00:06:30,210 --> 00:06:33,050
我们执行它来导出新状态。

118
00:06:33,050 --> 00:06:35,290
但你推翻了旧的状态，

119
00:06:35,290 --> 00:06:37,910
它不会由反应自动合并

120
00:06:37,910 --> 00:06:39,740
如果你想合并

121
00:06:39,740 --> 00:06:42,210
因为你正在管理一些状态对象，

122
00:06:42,210 --> 00:06:46,120
您必须自己编写此逻辑。

123
00:06:46,120 --> 00:06:49,780
使用基于类的组件和 setState 是不同的，

124
00:06:49,780 --> 00:06:52,870
有反应合并这个给你。

125
00:06:52,870 --> 00:06:56,020
当然，我并不总是想将其设置为 false，

126
00:06:56,020 --> 00:06:59,010
我想将其设置为与之前相反的值

127
00:06:59,010 --> 00:07:00,890
因此这里设置状态

128
00:07:00,890 --> 00:07:03,810
就像 useState 的状态更新函数一样

129
00:07:04,670 --> 00:07:09,630
也支持这样的更新功能。

130
00:07:09,630 --> 00:07:13,480
所以这里我们也可以传递一个函数给setState

131
00:07:13,480 --> 00:07:16,720
替代具有新状态的对象。

132
00:07:16,720 --> 00:07:18,260
我们应该这样做

133
00:07:18,260 --> 00:07:22,420
如果我们的新状态取决于之前的状态。

134
00:07:22,420 --> 00:07:24,040
尽管如此，这还不够

135
00:07:24,040 --> 00:07:27,090
只返回一个像这样的新状态值，

136
00:07:27,090 --> 00:07:30,110
因为在这里我会返回一些无效的东西

137
00:07:30,110 --> 00:07:31,990
因为我们的状态是一个对象。

138
00:07:31,990 --> 00:07:35,540
相反，我们必须在这里稍微改变一下

139
00:07:35,540 --> 00:07:37,660
并返回一个新对象

140
00:07:37,660 --> 00:07:40,700
就像你必须传递我们的对象来设置状态一样

141
00:07:40,700 --> 00:07:42,390
如果你使用那个函数形式

142
00:07:42,390 --> 00:07:45,090
你必须返回一个对象。

143
00:07:45,090 --> 00:07:50,090
在那里，我说 showUsers 为 curState.showUsers

144
00:07:50,580 --> 00:07:52,023
并将其反转。

145
00:07:53,070 --> 00:07:56,240
再说一次，我们在这里返回的内容将被合并

146
00:07:56,240 --> 00:07:57,610
与旧状态。

147
00:07:57,610 --> 00:08:01,633
所以这里的第二个状态块不会丢失。

148
00:08:02,620 --> 00:08:05,260
这就是我们更新状态的方式。

149
00:08:05,260 --> 00:08:09,160
现在要使用它，我们进入 render 方法

150
00:08:09,160 --> 00:08:11,400
我需要我的状态的地方

151
00:08:11,400 --> 00:08:15,620
现在我们可以在这里访问 this.state.showUsers

152
00:08:15,620 --> 00:08:18,080
访问此状态对象

153
00:08:18,080 --> 00:08:21,500
然后是 showUsers 属性，

154
00:08:21,500 --> 00:08:25,670
我们在这里设置并在这里管理和更新。

155
00:08:25,670 --> 00:08:29,423
我们在所有需要这种状态的地方都这样做。

156
00:08:31,840 --> 00:08:35,090
当然，现在我也想到达用户列表，

157
00:08:35,090 --> 00:08:37,669
因此我会在这里获取这个常数

158
00:08:37,669 --> 00:08:39,630
并将其添加到我的渲染方法中

159
00:08:41,280 --> 00:08:44,480
因为我们当然仍然可以定义帮助

160
00:08:44,480 --> 00:08:46,870
或者在渲染方法中像这样同意，

161
00:08:46,870 --> 00:08:49,563
一切都是有效且有效的。

162
00:08:50,690 --> 00:08:53,680
但缺少一件事，最后一件事

163
00:08:53,680 --> 00:08:55,680
这就是这里的方法。

164
00:08:55,680 --> 00:08:58,540
我添加了toggleUserHandler方法，

165
00:08:58,540 --> 00:09:03,270
但你不会像这样使用它来调用它。

166
00:09:03,270 --> 00:09:06,510
相反，它是这里这个子句的一个方法

167
00:09:06,510 --> 00:09:11,510
因此我们需要指向这个toggleUserHandler

168
00:09:11,540 --> 00:09:14,883
指向此类的此方法部分。

169
00:09:15,970 --> 00:09:18,110
但即使这样也行不通

170
00:09:18,110 --> 00:09:22,170
由于 JavaScript 中的工作方式。

171
00:09:22,170 --> 00:09:24,400
这与反应无关

172
00:09:24,400 --> 00:09:28,860
这个关键字在 JavaScript 中可能很棘手。

173
00:09:28,860 --> 00:09:30,440
附上你找到的资源

174
00:09:30,440 --> 00:09:33,073
这可以让您了解更多相关信息。

175
00:09:34,230 --> 00:09:37,090
最后你需要做的是你需要确保

176
00:09:37,090 --> 00:09:41,300
你的方法中的 this 关键字

177
00:09:41,300 --> 00:09:44,470
指的是周围的类

178
00:09:44,470 --> 00:09:47,070
默认情况下不会，

179
00:09:47,070 --> 00:09:51,880
当您的方法被任何事件调用时，例如单击。

180
00:09:51,880 --> 00:09:56,880
因此，为了解决这个问题，我们可以使用 bind 并绑定 this

181
00:09:58,090 --> 00:10:00,620
这只是意味着这个关键字

182
00:10:00,620 --> 00:10:03,420
在这个方法里面

183
00:10:03,420 --> 00:10:08,420
现在设置为具有相同的上下文或相同的值

184
00:10:08,690 --> 00:10:12,810
当评估此代码时作为 this 关键字

185
00:10:12,810 --> 00:10:16,803
这里这个关键字将引用这个类。

186
00:10:18,750 --> 00:10:23,090
再次强调，这与 JavaScript 的工作原理有关。

187
00:10:23,090 --> 00:10:26,760
在功能组件世界中不需要它

188
00:10:26,760 --> 00:10:29,340
因为我们只是定义了一个函数

189
00:10:29,340 --> 00:10:31,870
就在我们指出它之前。

190
00:10:31,870 --> 00:10:34,670
我们根本不使用 this 关键字

191
00:10:34,670 --> 00:10:37,163
因为我们不是在班级里工作。

192
00:10:38,610 --> 00:10:40,630
这样，我们就可以再次删除

193
00:10:40,630 --> 00:10:43,310
功能组件或注释掉的

194
00:10:44,240 --> 00:10:46,120
然后保存一切。

195
00:10:46,120 --> 00:10:49,060
现在如果我重新加载，我们会收到一个错误，

196
00:10:49,060 --> 00:10:52,550
必须在派生类中调用超级构造函数，

197
00:10:52,550 --> 00:10:54,360
这确实是事实。

198
00:10:54,360 --> 00:10:57,080
当您将构造函数添加到类中时

199
00:10:57,080 --> 00:11:02,080
如果你扩展另一个类，你需要调用 super

200
00:11:02,120 --> 00:11:05,130
它调用超类的构造函数

201
00:11:05,130 --> 00:11:07,740
所以如果该类继承自。

202
00:11:07,740 --> 00:11:11,300
这样，如果我们重新加载这个作品

203
00:11:11,300 --> 00:11:16,300
现在它像以前一样仅适用于类组件。

204
00:11:16,410 --> 00:11:17,760
正如你所知，

205
00:11:17,760 --> 00:11:21,903
这只是编写组件的不同方式。

206
00:11:22,930 --> 00:11:26,140
当然，现在我们也可以去掉 useState 导入

207
00:11:26,140 --> 00:11:27,830
因为我们不再使用它了

208
00:11:27,830 --> 00:11:29,770
正如之前提到的，

209
00:11:29,770 --> 00:11:33,320
您也不能在基于类的组件中使用它。

210
00:11:33,320 --> 00:11:36,023
那里不能使用任何反应钩子。


